package io.dy.stream;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.function.*;

/**
 * @author : dmj
 * @date: 2024/12/17 4:30 下午
 * @description: 自定义简易流
 */
public class DyStream<T> {

    private final Collection<T> collection;

    private DyStream(Collection<T> collection) {
        this.collection = collection;
    }

    /**
     * 生成流的静态方法
     * @param <T>
     * @return
     */
    public static<T> DyStream<T> of(Collection<T> collection){
        return new DyStream<>(collection);
    }


    /**
     * 过滤
     * @param predicate
     * @return
     */
    public DyStream<T> filter(Predicate<T> predicate){
        List<T> filterList = new ArrayList<>();
        for (T t : DyStream.this.collection) {
            if(predicate.test(t)){
                filterList.add(t);
            }
        }
        return new DyStream<>(filterList);
    }

    /**
     * 生成新值
     * @param function
     * @param <U>
     * @return
     */
    public <U> DyStream<U> map(Function<T,U> function){
        List<U> mapList = new ArrayList<>();
        for (T t : DyStream.this.collection) {
            mapList.add(function.apply(t));
        }
        return new DyStream<>(mapList);
    }

    /**
     * 消费
     * @param consumer
     */
    public void foreach(Consumer<T> consumer){
        for (T t : DyStream.this.collection) {
            consumer.accept(t);
        }
    }

    /**
     * 聚合操作
     * @return
     */
    public T reduce(T seed, BinaryOperator<T> operator){
        T p = seed;
        for (T t : DyStream.this.collection) {
            p = operator.apply(p, t);
        }
        return p;
    }

    /**
     * 数据收集
     * @param supplier 容器函数
     * @param biConsumer 收集方式的函数
     * @param <C>
     * @return
     */
    public <C> C collect(Supplier<C> supplier, BiConsumer<C,T> biConsumer){
        C c = supplier.get();
        for (T t : DyStream.this.collection) {
            biConsumer.accept(c, t);
        }
        return c;
    }
}
